import axios, {
    AxiosError,
    AxiosInstance,
    AxiosRequestHeaders,
    AxiosResponse,
    InternalAxiosRequestConfig,
} from 'axios'

import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import { getToken, removeToken } from '../../utils/auth'
import qs from 'qs'
import { config } from './config'
// import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth'
import errorCode from './errorCode'
// import.meta
// import { loginFlagStore } from '../../store'
// const store = loginFlagStore()
const { result_code, base_url, request_timeout } = config

// 需要忽略的提示。忽略后，自动 Promise.reject('error')
const ignoreMsgs = [
    '无效的刷新令牌', // 刷新令牌被删除时，不用提示
    '刷新令牌已过期', // 使用刷新令牌，刷新获取新的访问令牌时，结果因为过期失败，此时需要忽略。否则，会导致继续 401，无法跳转到登出界面
]
// 是否显示重新登录
export const isRelogin = { show: false }
// 请求白名单，无须token的接口
const whiteList: string[] = ['/login']

// 创建axios实例
const service: AxiosInstance = axios.create({
    baseURL: base_url, // api 的 base_url
    timeout: request_timeout, // 请求超时时间
    withCredentials: false, // 禁用 Cookie 等信息
})

// request拦截器
service.interceptors.request.use(
    async (config: InternalAxiosRequestConfig) => {
        // 是否需要设置 token
        let isToken = true
        whiteList.forEach((v: string) => {
            if (config.url && config.url.includes(v)) {
                isToken = false
            }
        })
        if (isToken) {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            const token: any = await getToken()
            config.headers.Authorization = 'Bearer ' + token // 让每个请求携带自定义token
        }
        const params = config.params || {}
        const data = config.data || false
        if (
            config.method?.toUpperCase() === 'POST' &&
            (config.headers as AxiosRequestHeaders)['Content-Type'] ===
                'application/x-www-form-urlencoded'
        ) {
            config.data = qs.stringify(data)
        }
        // get参数编码
        if (config.method?.toUpperCase() === 'GET' && params) {
            config.params = {}
            const paramsStr = qs.stringify(params, { allowDots: true })
            if (paramsStr) {
                config.url = config.url + '?' + paramsStr
            }
        }
        return config
    },
    (error: AxiosError) => {
        // Do something with request error
        console.log(error) // for debug
        Promise.reject(error)
    },
)

// response 拦截器
service.interceptors.response.use(
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    async (response: AxiosResponse<any>) => {
        let { data } = response
        // const config = response.config
        if (!data) {
            // 返回“[HTTP]请求没有返回值”;
            throw new Error()
        }
        // 未设置状态码则默认成功状态
        // 二进制数据则直接返回，例如说 Excel 导出
        if (
            response.request.responseType === 'blob' ||
            response.request.responseType === 'arraybuffer'
        ) {
            // 注意：如果导出的响应为 json，说明可能失败了，不直接返回进行下载
            if (response.data.type !== 'application/json') {
                return response.data
            }
            data = await new Response(response.data).json()
        }
        const code: string = data.code || result_code
        // 获取错误信息
        const msg =
            data.msg ||
            errorCode[code as keyof typeof errorCode] ||
            errorCode['default']
        if (ignoreMsgs.indexOf(msg) !== -1) {
            // 如果是忽略的错误码，直接返回 msg 异常
            return Promise.reject(msg)
        } else if (+code === 401) {
            handleAuthorized()
        } else if (+code === 500) {
            ElMessage.error('服务器错误,请联系管理员!')
            return Promise.reject(new Error(msg))
        } else if (+code !== 200) {
            if (msg === '无效的刷新令牌') {
                // hard coding：忽略这个提示，直接登出
                console.log(msg)
                return handleAuthorized()
            } else {
                ElNotification.error({ title: msg })
            }
            return Promise.reject('error')
        } else {
            return data
        }
    },
    (error: AxiosError) => {
        console.log('err' + error) // for debug
        let { message } = error
        if (message === 'Network Error') {
            message = '操作失败,系统异常!'
        } else if (message.includes('timeout')) {
            message = '接口请求超时,请刷新页面重试!'
        } else if (message.includes('Request failed with status code')) {
            message =
                '请求出错，请稍候重试' + message.substr(message.length - 3)
        }
        ElMessage.error(message)
        return Promise.reject(error)
    },
)

const handleAuthorized = () => {
    if (!isRelogin.show) {
        // 如果已经到重新登录页面则不进行弹窗提示
        if (window.location.href.includes('plugin_login?redirect=')) {
            return
        }
        isRelogin.show = true
        ElMessageBox.confirm('登录超时,请重新登录!', '系统提示', {
            showCancelButton: false,
            closeOnClickModal: false,
            showClose: false,
            confirmButtonText: '重新登录',
            type: 'warning',
        }).then(async () => {
            // 重置静态路由表
            // 删除store里的登陆状态
            // store.setLoginFlag(false)
            // 移除token
            await removeToken()
            isRelogin.show = false
            // 登陆过期刷新页面
            window.location.reload()
        })
    }
    return Promise.reject('登录超时,请重新登录!')
}
export { service }
